<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>对象作业</title>
  </head>
  <body>
    <script>
      //～加油～
      /* 
        1. 创建一个对象有那两种方式
         */
      //(1) 字面量方式创建对象 var obj = {}
      // (2) 内置构造函数创建对象 var obj = new Object() 
        
      /* 
        2. 请举例说明，对象的基本操作的两种语法
        */
      // (1)点语法
      // 准备一个空对象
      var obj = {};
      // 增加语法 对象名.键名=值
      obj.year = 2022;
      obj.month = 8;
      obj.day = 2;
      // 删除语法 delete 对象名.键名
      delete obj.year;
      // 修改语法 对象名.键名=值
      obj.month = 7;
      // 查语法 对象名.键名
      console.log(obj.day);

      // (2)数组关联语法
      // 准备一个空对象
      var obj2 = {};
      // 增加语法 对象名["键名"]=值
      obj2["name"] = "Jan";
      obj2["age"] = 18;
      // 删除语法 delete 对象名["键名"]
      delete obj2["name"]
      // 修改语法 对象名["键名"]=值
      obj2["age"] = 20;
      // 查语法 对象名["键名"]
      console.log(obj2["age"]);


      /*
        3.对象的curd，两种语法有什么区别 
        */

      // (1)对于键名
      // 只要符合变量命名规则和规范的键名，两种语法都可以
      // 纯数字只能用数组关联语法，不可以用点语法
      // 对于带有特殊符号的，只能用数组关联语法，不能用点语法
      // (2)对于变量
      // 点语法不能和变量产生联系，始终都是访问对象的某一个准确的键名
      // 数组关联语法[]内写的是一个变量，解析出来填充在[]里面，使对象和变量产生关联

      /* 
        4.对象怎么遍历？那个是键名，那个是键值
        */

      // 对象没法使用for遍历，而是用for in进行遍历
      // 语法 for(var 变量名 in 对象名){}
      var obj3 = {
        name: "Jan",
        age: 18,
        from: "GZ"
      }
      for(var a in obj3){
        console.log(a, obj3[a]);//a是键名，obj3[a]是键值
      }

      /* 
        5.简单和复杂数据类型在存储上的区别是什么？
        那赋值和比较上的区别又是什么？
        */

      // 简单的数据类型存在栈里面
      // 复杂的数据类型在栈里面存放的是地址，真实的数据存放在堆里面

      // 简单数据类型的赋值两个变量之间没有任何关系，即使改变一个变量，另一个变量也不会改变
      // 复杂数据类型的赋值式把变量存储在地址进行赋值，
      // 因为两个变量操作的是同一个存储空间，所以修改任意一个变量的数据，
      // 另一个也会跟着改变

      // 简单数据类型是值与值的比较
      // 复杂数据类型是地址和地址的比较

      /* 
        6.如下代码会打印什么？请写出分析过程
        */
        var b = "boy";
        console.log(b);//boy，全局定义了var b = "boy" 
        function fighting() {
          console.log(a);//undefined，只定义了a但没有赋值
          console.log(c);//undefined，同理 目前只给c定义了但没有赋值
          if (a === "apple") {
            a = "Alice";
          } else {
            a = "Ada";
          }
          console.log(a);//Ada，根据上面if判断语句，a==="apple"不成立，所以执行了a = "Ada"
          var a = "Andy";
          middle();
          function middle() {
            console.log(c++);//NaN，目前c仍然没有进行赋值，c++相当于转化成数字，但c没有进行数字的赋值，所以是Not a Number
            var c = 100;
            console.log(++c);//101，上面对c进行了赋值为100，++c是先让c进行自增在执行，所以是101
            small();
            function small() {
              console.log(a);//Andy，本作用域内没有对a进行定义和赋值，所以向父级找，找到var a = "Andy"
            }
          }
          var c = (a = 88);
          function bottom() {
            b = "baby";
            console.log(b);// baby，给b赋值了"baby"
          }
          bottom();
        }
        fighting();
        console.log(b);//baby，因为在bottom函数内给b赋值了"baby"但bottom作用域内没有定义b，所以就会向父级寻找定义了的b，而只有在全局中有定义了b，所以给全局的b赋值了baby
    </script>
  </body>
</html>
